package org.bdware.irp.irplib.core;

import org.bdware.irp.irplib.util.IrpCommon;
/**
 *
 * Description:
 * <p>
 *  Message Header implementation
 * </p>
 * Time:2021-07<br>
 *
 * @author：pku<br>
 * @version:$Revision: 1.0 $<br>
 * @since 1.0
 */
public class IrpMessageHeader {
    public int opCode;
    public int responseCode;
    private int opFlag;
    public short siteInfoSerialNumber;
    public byte recursionCount;
    public byte reservedSpace;
    public int expirationTime;      //set to zero if no expiration is expected.
    public int bodyLength;      //the number of octets in the Message Body

    //bit flag in opFlag
    private boolean authoritativeFlag;      //exchange message with primary service site
    private boolean certifiedFlag;      //sign response with digital signature
    private boolean encryptionFlag;     //encrypt response using the pre-established session key
    private boolean recursiveFlag;      //asks the server to forward the query
    private boolean cacheAuthenticationFlag;    //asks the caching server (if any) to authenticate any server response
    private boolean contiNuousFlag;     //more messages that are part of the same request (or response) will follow
    private boolean keepConnectionFlag;     //keep the TCP connection open (after the response is sent back)
    private boolean publicOnlyFlag;     //asking for handle values that have the PUB_READ permission
    private boolean requestDigestFlag;      //include in response the message digest of the request

    /**
     * IrpMessageHeader Constructor
     */
    public IrpMessageHeader(){
        this.opCode = IrpMessageCode.OC_RESERVED;
        this.responseCode = IrpMessageCode.RC_RESERVED;
        this.siteInfoSerialNumber = 0;
        this.recursionCount = 0;
        this.reservedSpace = 0;
        this.expirationTime = 0;
        this.bodyLength = 0;
        this.setFlagsByOpFlag(0);
    }
    public IrpMessageHeader(int opCode){
        this.opCode = opCode;
    }

    public IrpMessageHeader(int opCode, int responseCode){
        this.opCode = opCode;
        this.responseCode = responseCode;
    }

    public IrpMessageHeader(int opCode, int responseCode, int opFlag, short siteInfoSerialNumber, byte recursionCount, int expirationTime,int bodyLength){
        this.opCode = opCode;
        this.responseCode = responseCode;
        this.siteInfoSerialNumber = siteInfoSerialNumber;
        this.recursionCount = recursionCount;
        this.reservedSpace = 0;
        this.expirationTime = expirationTime;
        this.bodyLength = bodyLength;
        this.setFlagsByOpFlag(opFlag);
    }

    /**
     * Operations for messageFlag
     */
    public void setFlagsByOpFlag(int opFlag){
        this.opFlag = opFlag;
        this.authoritativeFlag = (opFlag < 0);
        this.certifiedFlag = ((int)(opFlag << 1 ) < 0);
        this.encryptionFlag = ((int)(opFlag << 2 ) < 0);
        this.recursiveFlag = ((int)(opFlag << 3 ) < 0);
        this.cacheAuthenticationFlag = ((int)(opFlag << 4 ) < 0);
        this.contiNuousFlag = ((int)(opFlag << 5 ) < 0);
        this.keepConnectionFlag = ((int)(opFlag << 6 ) < 0);
        this.publicOnlyFlag = ((int)(opFlag << 7 ) < 0);
        this.requestDigestFlag = ((int)(opFlag << 8 ) < 0);
    }

    public int getOpFlagByFlags(){
        this.opFlag = 0;
        if(this.authoritativeFlag) this.opFlag = (int)(this.opFlag | 0x80000000);
        if(this.certifiedFlag) this.opFlag = (int)(this.opFlag | 0x40000000);
        if(this.encryptionFlag) this.opFlag = (int)(this.opFlag | 0x20000000);
        if(this.recursiveFlag) this.opFlag = (int)(this.opFlag | 0x10000000);
        if(this.cacheAuthenticationFlag) this.opFlag = (int)(this.opFlag | 0x08000000);
        if(this.contiNuousFlag) this.opFlag = (int)(this.opFlag | 0x04000000);
        if(this.keepConnectionFlag) this.opFlag = (int)(this.opFlag | 0x02000000);
        if(this.publicOnlyFlag) this.opFlag = (int)(this.opFlag | 0x01000000);
        if(this.requestDigestFlag) this.opFlag = (int)(this.opFlag | 0x00800000);
        return this.opFlag;
    }

    public boolean getAuthoritativeFlag(){
        return this.authoritativeFlag;
    }

    public boolean getCertifiedFlag(){
        return this.certifiedFlag;
    }

    public boolean getEncryptionFlag(){
        return this.encryptionFlag;
    }

    public boolean getRecursiveFlag(){
        return this.recursiveFlag;
    }

    public boolean getCacheAuthenticationFlag(){
        return this.cacheAuthenticationFlag;
    }

    public boolean getContiNuousFlag(){
        return this.contiNuousFlag;
    }

    public boolean getKeepConnectionFlag(){
        return this.keepConnectionFlag;
    }

    public boolean getPublicOnlyFlag(){
        return this.publicOnlyFlag;
    }

    public boolean getRequestDigestFlag(){
        return this.requestDigestFlag;
    }

    public void setAuthoritativeFlag(boolean authoritativeFlag){
        this.authoritativeFlag = authoritativeFlag;
    }

    public void setCertifiedFlag(boolean certifiedFlag){
        this.certifiedFlag = certifiedFlag;
    }

    public void setEncryptionFlag(boolean encryptionFlag){
        this.encryptionFlag = encryptionFlag;
    }

    public void setRecursiveFlag(boolean recursiveFlag){
        this.recursiveFlag = recursiveFlag;
    }

    public void setCacheAuthenticationFlag(boolean cacheAuthenticationFlag){
        this.cacheAuthenticationFlag = cacheAuthenticationFlag;
    }

    public void setContiNuousFlag(boolean contiNuousFlag){
        this.contiNuousFlag = contiNuousFlag;
    }

    public void setKeepConnectionFlag(boolean keepConnectionFlag){
        this.keepConnectionFlag = keepConnectionFlag;
    }

    public void setPublicOnlyFlag(boolean publicOnlyFlag){
        this.publicOnlyFlag = publicOnlyFlag;
    }

    public void setRequestDigestFlag(boolean requestDigestFlag){
        this.requestDigestFlag = requestDigestFlag;
    }
}
